package com.jaws.demo.controller;

import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

import java.util.Random;

import javax.annotation.Resource;
import javax.validation.Valid;

import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.jaws.core.common.page.Page;
import com.jaws.core.common.vo.OpRequest;
import com.jaws.core.common.vo.OpResponse;
import com.jaws.core.compatible.service.CacheService;
import com.jaws.demo.common.exception.ClientDemoExceptionCode;
import com.jaws.demo.configuration.ClientDemoConfigProperties;
import com.jaws.demo.service.MailService;
import com.jaws.demo.feign.AccountFeign;
import com.jaws.demo.feign.CloudServerFeign;
import com.jaws.demo.feign.VAccountFeign;
import com.jaws.demo.mq.MqProvider;
import com.jaws.demo.service.AsyncService;
import com.jaws.demo.service.ClientDemoService;
import com.jaws.demo.vo.UserQueryVO;
import com.jaws.demo.vo.UserVO;
import com.yyfax.vaccount.vo.AccountInitReq;
import com.yyfax.vaccount.vo.QueryAccountLogReq;
import com.yyfax.vaccount.vo.QueryAccountLogRsp;

@RestController
@RefreshScope
@Slf4j
public class TestController {

	@Resource
	private MqProvider mqProvider;

	@Resource
	private ClientDemoService clientDemo;

	@Resource
	private AccountFeign account;

	@Resource
	private CloudServerFeign cloudServer;

	@Resource
	private RedisTemplate<Object, Object> redisTemplate;

	@Resource
	private ClientDemoConfigProperties clientDemoConfig;

	@Resource
	private CacheService cacheService;

	@Value("${jaws.apollo.test}")
	private String value;

	@Resource
	private AsyncService asyncService;
	
	@Resource
	private InetUtils inetUtils;
	
	@Resource
	private MailService mailService;
	
	// @Value("${foo}")
	// String foo;
	//
	// @Value("${mj.test}")
	// String mjTest;

	@PostMapping(value = "/cache")
	@ApiOperation(value = "测试缓存信息")
	public OpResponse cache(@ApiParam(value = "请求参数", required = true) @RequestBody @Valid OpRequest<String> req) {
//		log.debug(Log.op("msg").kv("key", "value").toString());
//		log.info(Log.op("msg2").kv("key2", "value2").toString());
//		log.warn(Log.op("msg4").kv("key4", "value4").toString());
//		log.error(Log.op("msg3").kv("key3", "value3").toString());
//		log.error(Log.op("msg8").kv("snowflake id", SnowflakeIdUtil.generate()).toString());
//		log.error(Log.op("msg8").kv("snowflake id", SnowflakeIdUtil.generate()).toString());

//		int DEFAULT_THREAD_NUM =(Runtime.getRuntime().availableProcessors() + 1 > 5) ? 6 : Runtime.getRuntime().availableProcessors() + 1;
//				
//		ThreadFactory nameThreadFactory = new ThreadFactoryBuilder().setNameFormat("test-%d").build();
//		ExecutorService executorService = new ThreadPoolExecutor(DEFAULT_THREAD_NUM, DEFAULT_THREAD_NUM, 0L, TimeUnit.MILLISECONDS,
//				new LinkedBlockingQueue<Runnable>(), nameThreadFactory);
//		
//		executorService.execute(new Runnable() {
//			@Override
//			public void run() {
//				log.error(Log.op("async").kv("msg9", "value9").toString());
//			}
//		});

//		asyncService.async();

//		UserVO user = new UserVO();
//		List ls = Lists.newArrayList();
//		ls.add(user);
//		user.setUsername("毛荐友金所");
//		log.info(Log.op("sense log test ").kv("UserVO list", ls).toString());
//		
//		Test test = new Test();
//		test.setTest1("aaaa");
//		log.info(Log.op("sense log test2 ").kv("test", test).toString());

//		if (log.isDebugEnabled()) {
//			log.debug("cccc");
//		}
		if (req.getParams().equals("1")) {
			throw ClientDemoExceptionCode.CACHE_ERROR.exp();
		} else {
			OpResponse response = OpResponse.success();
			response.setContent("hi");
			this.redisTemplate.opsForValue().set("mjTest" + new Random().nextInt(10000), new Random().nextInt(10000));
			return response;
		}
	}

	/**
	 * 配置
	 *
	 * @return
	 * @author maojian
	 * @date 2018-03-12 10:56:17
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试配置信息")
	@PostMapping(value = "/config")
	public String config() {
		// return clientDemoConfig.toString();
		return value;
	}

	/**
	 * mq操作
	 *
	 * @author maojian
	 * @date 2018-03-12 10:56:45
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试发送队列消息")
	@PostMapping(value = "/mq")
	public void mq() {
		mqProvider.send();
	}

	/**
	 * 本地数据库
	 *
	 * @return
	 * @author maojian
	 * @date 2018-03-12 10:56:29
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试mybatis查询")
	@GetMapping(value = "/mybatis")
	public OpResponse mybatis(@ApiParam(value = "用户id", required = true) @RequestParam String userId) {
		OpResponse response = OpResponse.success();
		response.setContent(clientDemo.queryAccountInfoByUser(userId));
		return response;
	}

	/**
	 * cloudServer get方法调用
	 *
	 * @param name
	 * @return
	 * @author maojian
	 * @date 2018-03-12 10:56:59
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试Get远程调用")
	@GetMapping(value = "/get/remoteCall")
	public OpResponse<String> remoteCallByGet(@ApiParam(value = "Get方法 远程调用参数", required = true) @RequestParam String name) {
		OpResponse<String> response = OpResponse.success();
		response.setContent(cloudServer.getHi(name).getContent());
		return response;
	}

	/**
	 * cloudServer post方法调用
	 *
	 * @return
	 * @author maojian
	 * @date 2018-03-12 10:57:31
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试POST远程调用")
	@PostMapping(value = "/post/remoteCall")
	public OpResponse<UserVO> remoteCallByPost(@ApiParam(value = "Get方法 远程调用参数", required = true) @RequestParam String name) {
		OpResponse<UserVO> response = OpResponse.success();
		UserVO user = new UserVO();
		user.setUsername(name);
		response.setContent(cloudServer.postHi(user).getContent());
		return response;
	}

	/**
	 * cloud server fallback
	 *
	 * @return
	 * @author maojian
	 * @date 2018-03-12 10:57:47
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试fallbackByGet")
	@GetMapping(value = "/get/fallback")
	public OpResponse fallbackByGet() {
		OpResponse response = OpResponse.success();
		response.setContent(cloudServer.getHiFallback());
		return response;
	}

	/**
	 * cloud server fallback excpetion
	 *
	 * @return
	 * @author maojian
	 * @date 2018-03-12 10:58:12
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试fallbackByPost")
	@PostMapping(value = "/post/fallback")
	public OpResponse fallbackByPost() {
		OpResponse response = OpResponse.success();
		response.setContent(cloudServer.postHiFallback());
		return response;
	}

	/**
	 * 账户查询
	 *
	 * @param userid
	 * @return
	 * @author maojian
	 * @date 2018-03-12 15:14:19
	 * @since v1.0.0
	 */
	@ApiOperation(value = "测试账户查询接口")
	@PostMapping(value = "/account/query")
	public OpResponse queryAccount(@ApiParam(value = "userid", required = true) @RequestParam String userid) {
		OpResponse response = OpResponse.success();
		OpRequest<UserQueryVO> req = new OpRequest<UserQueryVO>();
		UserQueryVO dto = new UserQueryVO();
		dto.setUserId(userid);
		req.setParams(dto);
		response.setContent(account.queryAccountInfoByUser(req));
		return response;
	}

	@RequestMapping(value = "/memcached")
	@ApiOperation(value = "测试memcached缓存信息")
	public OpResponse memcached(@ApiParam(value = "请求参数", required = true) @RequestBody @Valid OpRequest<String> req) {
		OpResponse response = OpResponse.success();
		cacheService.set("mjtest", req.getParams());
		response.setContent(cacheService.get("mjtest"));
		return response;
	}

	@PostMapping(value = "/testRps")
	@ApiOperation(value = "testRps")
	public OpResponse testRps(@ApiParam(value = "请求参数", required = true) @RequestBody @Valid OpRequest<String> req) {
		return OpResponse.success();
	}

	@PostMapping(value = "/validator")
	@ApiOperation(value = "validator")
	public OpResponse testValidator(@ApiParam(value = "请求参数", required = true) @RequestBody @Valid OpRequest<UserVO> req) {
		return OpResponse.success();
	}

//	public static void main(String[] args) {
//		String separatorPattern = ",|;|\\|";
//		String packName = "com.jaws.demo.vo,com.jaws.demo.vo1";
//		Iterable<String> paths = Splitter.onPattern(separatorPattern).split(packName);
//		FilterBuilder filter = new FilterBuilder();
//		filter.includePackage("com.jaws.core.common.validator");
//		List<URL> result = new ArrayList<URL>();
//		for (String path : paths) {
//			filter.includePackage(path);
//			result.addAll(ClasspathHelper.forPackage(path));
//		}
//		Reflections reflections = new Reflections(new ConfigurationBuilder()
//				.filterInputsBy(filter)
//				.setScanners(new SubTypesScanner().filterResultsBy(filter), new TypeAnnotationsScanner().filterResultsBy(filter), new FieldAnnotationsScanner().filterResultsBy(filter),
//						new MemberUsageScanner().filterResultsBy(filter), new MethodAnnotationsScanner().filterResultsBy(filter), new MethodParameterScanner()).setUrls(result));
//
//		Set<Field> fields = reflections.getFieldsAnnotatedWith(WechatNicknameValid.class);
//		Set<Field> fields2 = reflections.getFieldsAnnotatedWith(MobileNoValid.class);
//
//
//		System.out.println(fields);
//		for (Field f : fields2) {
//			System.out.println(reflections.getFieldUsage(f));
//		}
//
//
//	}


	@Resource
	VAccountFeign vAccountFeign;

	@ApiOperation(value = "测试账户查询接口")
	@PostMapping(value = "/test/feign")
	public OpResponse testFeignClient() {
		OpResponse response = OpResponse.success();

		AccountInitReq req = new AccountInitReq();
		req.setUserId("aaa");
		response.setContent(vAccountFeign.initAccount(req));
		return response;
	}

	@ApiOperation(value = "测试账户查询接口")
	@PostMapping(value = "/test/error")
	public OpResponse testFeignError() {
		OpResponse response = OpResponse.success();
		vAccountFeign.test();
		return response;
	}

	@ApiOperation(value = "测试Page")
	@PostMapping(value = "/test/testPage")
	public OpResponse<Page<QueryAccountLogRsp>> testPage(QueryAccountLogReq req) {
		OpResponse<Page<QueryAccountLogRsp>> op = vAccountFeign.queryAccountLog(req);

		return op;
	}
	
	@ApiOperation(value = "测试发送邮件")
	@PostMapping(value = "/test/send_email")
	public OpResponse<Page<QueryAccountLogRsp>> sendEmail() {
		mailService.send();
		return OpResponse.success();
	}

}
